import { projectMercator } from "./Projection.Mercator";
import { toLatLng } from "../geometry/LatLng";
import { toPoint } from "../geometry/Point";
// import { drawImage, drawPoint } from "../drawing/drawing";
import * as Draw from "../drawing/drawing";
import { getGaoDeTileUrl, getWMSUrl } from "../layer/TileLayer";

export class WMS {
  // 缩放级别
  zoom;
  // 中心点
  centerPoint;
  crspro = projectMercator();
  // 地球半径
  EARTH_RAD = 6378137;
  // 地球周长
  EARTH_PERIMETER = 2 * Math.PI * this.EARTH_RAD;
  // 瓦片像素
  TILE_SIZE = 256;
  TileCache = [];
  office = toPoint(0, 0);
  baseLayer = [];
  drawLayer = [];
  animate = false; // 动画
  lng;
  crspro = toMercator();
  lat;
  render;
  centerMercator = toPoint(0, 0);

  constructor({ lng, lat, zoom, ctx, canvas, drawLayer, animate }) {
    this.lng = lng;
    this.lat = lat;
    this.canvas = canvas;
    this.ctx = ctx;
    this.zoom = zoom;
    this.drawLayer = drawLayer;
    this.centerPoint = toPoint(lng, lat);
    this.width = this.canvas.width;
    this.height = this.canvas.height;
    this.ctx.clearRect(0, 0, this.width, this.height);
    this.updata(this.lng, this.lat);
    this.centerMercator = this.getPxFromLngLat(lng, lat, zoom);
    this.animate = animate;
    if (animate) {
      this.start();
    }
  }

  scaleMap({ lng, lat, zoom }) {
    this.centerMercator = this.getPxFromLngLat(lng, lat, zoom);
    this.zoom = zoom;
    this.TileCache = [];
    this.office = toPoint(0, 0);
    this.updata(lng, lat);
  }

  updata(lng, lat) {
    console.log("进一次updata");
    const { zoom, ctx } = this;
    // WMS 移动过偏移量要重置

    const mer = this.crspro.lngLatToMercator(lng, lat);

    // 当前层级分辨率
    let resolution = this.getResolution(zoom);
    const centerToMercator = toPoint(mer.lng, mer.lat);

    const mercatorLeftTop = centerToMercator.subtract(
      toPoint(250 * resolution, -250 * resolution)
    );
    const mercatorRightBottom = centerToMercator.subtract(
      toPoint(-250 * resolution, 250 * resolution)
    );

    const lnglatLeftTop = this.crspro.unproject(mercatorLeftTop);

    const lnglatRightBottom = this.crspro.unproject(mercatorRightBottom);

    const mk = [];
    mk.push(lnglatLeftTop.lng);
    mk.push(lnglatRightBottom.lat);
    mk.push(lnglatRightBottom.lng);
    mk.push(lnglatLeftTop.lat);
    const aa = getWMSUrl({
      url: "http://localhost:6080/arcgis/rest/services/newhaha/haha/MapServer",
      parameters: {
        dpi: 96,
        transparent: true,
        format: "png8",
        imageSR: 4490,
        f: "image",
        bboxSR: 4490,
        bbox: mk.toString(),
        size: "500,500",
      },
    });
    console.log(aa);

    this.TileCache = [
      {
        image: new Image(),
        url: aa,
      },
    ];
    this.office = toPoint(0, 0);
    this.renderGrap(aa);
  }
  renderGrap(url) {
    this.TileCache.forEach((item) => {
      this.loadedImg(item, (e) => {
        this.drawImagesss(e);
      });
    });
  }
  renderDraw() {
    this.drawLayer.forEach((item) => {
      if (item.type === "point") {
        this.drawPointhandle({ coordinate: item.coordinate });
        this.drawTexthandle({
          coordinate: item.coordinate,
          text: item.text,
          marginTop: 25,
        });
      } else if (item.type === "polygon") {
        this.drawPolygonhandle({
          coordinates: item.coordinates,
        });
      }
    });
  }
  drawImagesss(e) {
    this.ctx.clearRect(0, 0, this.width, this.height);
    Draw.drawImage({
      ctx: this.ctx,
      image: e.image,
      x: 0 + this.office.x,
      y: 0 + this.office.y,
      w: this.canvas.width,
      h: this.canvas.height,
    });
  }

  moveTo(offi) {
    this.office = offi;
    console.log(this.office);
    // this.ctx.clearRect(0, 0, this.width, this.height);
    this.TileCache.forEach((e) => {
      this.drawImagesss(e);
    });
  }

  /**
   * 获取地图应该显示的范围编号
   * @param {*} centerTile  中心点瓦片坐标
   * @param {*} offset 偏移量
   * @returns
   */
  getRange(centerTile, offset) {
    // 计算瓦片数量
    let rowMinNum = Math.ceil((this.width / 2 - offset.x) / this.TILE_SIZE); // 左
    let colMinNum = Math.ceil((this.height / 2 - offset.y) / this.TILE_SIZE); // 上
    let rowMaxNum = Math.ceil(
      (this.width / 2 - (this.TILE_SIZE - offset.x)) / this.TILE_SIZE
    ); // 右
    let colMaxNum = Math.ceil(
      (this.height / 2 - (this.TILE_SIZE - offset.y)) / this.TILE_SIZE
    ); // 下
    const tiles = [];
    // console.log(rowMinNum, colMinNum, rowMaxNum, colMaxNum);
    // 从上到下，从左到右，加载瓦片
    for (let i = -rowMinNum; i <= rowMaxNum; i++) {
      for (let j = -colMinNum; j <= colMaxNum; j++) {
        // if (
        //   centerTile.x + i < Math.pow(this.zoom, 2) &&
        //   centerTile.y + j < Math.pow(this.zoom, 2)
        // ) {
        const obj = {
          image: new Image(),
          x: centerTile.x + i,
          y: centerTile.y + j,
          n: i * this.TILE_SIZE - offset.x - this.office.x + this.width / 2,
          k: j * this.TILE_SIZE - offset.y - this.office.y + this.height / 2,
          z: this.zoom,
        };

        tiles.push(obj);
        // }
      }
    }
    return tiles;
  }

  /**
   * 加载图片的回调函数
   * @param {*} sources
   * @param {*} callback
   */
  loadedImg(sources, callback) {
    const { image, url } = sources;
    image.src = url;
    image.onload = () => {
      callback(sources);
    };
  }

  /**
   * 获取某一层级下的分辨率
   * @param {*} n
   * @returns
   */
  getResolution = (n) => {
    const tileNums = Math.pow(2, n);
    const tileTotalPx = tileNums * this.TILE_SIZE;
    return this.EARTH_PERIMETER / tileTotalPx;
  };

  /**
   * 根据经度纬度层级算出行列
   * @param {*} olng
   * @param {*} olat
   * @param {*} zoom
   * @returns
   */
  getTileRowAndCol = (olng, olat, zoom) => {
    let { lng, lat } = this.crspro.lngLatToMercator(olng, olat);
    lng += this.EARTH_PERIMETER / 2; // ++
    lat = this.EARTH_PERIMETER / 2 - lat; // ++
    let resolution = this.getResolution(zoom);
    let row = Math.floor(lng / resolution / this.TILE_SIZE);
    let col = Math.floor(lat / resolution / this.TILE_SIZE);
    return toPoint(row, col);
  };
  // 根据经纬度算出投影
  getPxFromLngLat = (lng, lat, z) => {
    const mer = this.crspro.lngLatToMercator(lng, lat);
    let _x = mer.lng;
    let _y = mer.lat;
    // 转成世界平面图的坐标
    _x += this.EARTH_PERIMETER / 2;
    _y = this.EARTH_PERIMETER / 2 - _y;
    let resolution = this.getResolution(z); // 该层级的分辨率
    // 米/分辨率得到像素
    let x = Math.floor(_x / resolution);
    let y = Math.floor(_y / resolution);
    return toPoint(x, y);
  };

  // 经纬度转图层上的点
  latLngToLayerPoint(lnglat) {
    const point = this.getPxFromLngLat(lnglat.lng, lnglat.lat, this.zoom);
    return point
      .subtract(this.centerMercator)
      .add(toPoint(this.width / 2, this.height / 2));
  }

  drawPointhandle({ coordinate, color = "#ff4f02", radius = 10 }) {
    const pos = this.latLngToLayerPoint(toLatLng(coordinate[0], coordinate[1]));
    Draw.drawPoint({
      ctx: this.ctx,
      x: pos.x + this.office.x,
      y: pos.y + this.office.y,
    });
  }
  drawTexthandle({
    coordinate,
    color = "#ff4f02",
    radius = 10,
    text,
    marginTop,
  }) {
    const pos = this.latLngToLayerPoint(toLatLng(coordinate[0], coordinate[1]));
    Draw.drawText({
      ctx: this.ctx,
      x: pos.x + this.office.x,
      y: pos.y + this.office.y,
      text,
      marginTop,
    });
  }

  drawPolygonhandle({
    coordinates,
    type = "polygon", // pylygon pylyline geo
    borderColor = "#000",
    borderWidth = 1,
    setLineDash = [3], // 可传入指譬如[3, 5]
    barckgroudColor = "#ccc",
    barckgroudColorHover = "",
    cursor = "default",
  }) {
    const tempCoordinates = coordinates.map((item) => {
      const pos = this.latLngToLayerPoint(toLatLng(item[0], item[1]));
      return [pos.x + this.office.x, pos.y + this.office.y];
    });

    Draw.drawPolygon({
      ctx: this.ctx,
      type,
      coordinates: tempCoordinates,
      borderColor,
      borderWidth,
      setLineDash,
      barckgroudColor,
      barckgroudColorHover,
      cursor,
    });
  }
  /**
   * 根据瓦片坐标获取该瓦片左上角的x,y
   * @param {*} loc
   * @returns
   */
  getPxFromTile(loc) {
    const { x, y } = loc;
    return toPoint(x * this.TILE_SIZE, y * this.TILE_SIZE);
  }
  start() {
    console.log("我一直在循环");
    // this.updata(this.lng, this.lat);
    this.render = requestAnimationFrame(this.start.bind(this));

    // if (this.animation) {
    //   let isf = false;
    //   this.animation.forEach((item) => {
    //     if (item.key === "mapCenterPosX") {
    //       this.mapCenterPos = [
    //         (this.mapCenterPos[0] += item.dur),
    //         this.mapCenterPos[1],
    //       ];
    //       if (this.mapCenterPos[0] > item.future) {
    //         isf = true;
    //       }
    //     } else if (item.key === "mapCenterPosY") {
    //       this.mapCenterPos = [
    //         this.mapCenterPos[0],
    //         (this.mapCenterPos[1] += item.dur),
    //       ];
    //     } else if (item.key === "scale") {
    //       this.scale = this.scale += item.dur;
    //     }
    //   });

    //   if (isf) {
    //     this.animation = null;
    //   }
    // }
  }
  destroy() {
    cancelAnimationFrame(this.render);
  }
}
